package com.sun.misc;


/**
 * 伪共享 https://blog.csdn.net/YingHuaNanHai/article/details/80815841
 *
 * 需要在 jvm 启动时设置 -XX:-RestrictContended 才会生效。
 *
 * 在 ConcurrentHashMap 类中有使用到
 */

public class ContendedDemo {


    /**
     * 将data对象的类型依次换位 Data DataPadding ContendedGroupData 三种类型，发现 DataPadding ContendedGroupData 执行时 readKeyThread线程时间明显下降，所以伪共享主要影响相同cache中的读的性能。
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        DataPadding data = new DataPadding();
        Long times = 100000*10000L;
        Thread modifyValueThread = new Thread(()->{
            Long startTime = System.currentTimeMillis();
            for(int i = 0 ;i< times;i++) {
                data.modifyTime++;
                data.value++;
            }
            System.out.println(Thread.currentThread().getName()+":"+(System.currentTimeMillis()-startTime));
        },"modifyValueThread");

        Thread modifyFlagThread = new Thread(()->{
            Long startTime = System.currentTimeMillis();
            for(int i = 0 ;i< times;i++) {
                data.flag  = false;
            }
            System.out.println(Thread.currentThread().getName()+":"+(System.currentTimeMillis()-startTime));
        },"modifyFlagThread");

        Thread readKeyThread = new Thread(()->{
            Long startTime = System.currentTimeMillis();
            for(int i = 0 ;i< times;i++) {
                char t = data.key;
                long creatTime = data.createTime;

            }
            System.out.println(Thread.currentThread().getName()+":"+(System.currentTimeMillis()-startTime));
        },"readKeyThread");

        modifyFlagThread.start();
        modifyValueThread.start();
        readKeyThread.start();
        Thread.sleep(1000*30);
    }

}
class Data{
    long modifyTime;
    boolean flag;
    volatile long createTime;
    char key;
    int value;
}

 class DataPadding{
    long a1,a2,a3,a4,a5,a6,a7,a8;//防止与前一个对象产生伪共享
    int value;
    long modifyTime;
    long b1,b2,b3,b4,b5,b6,b7,b8;//防止不相关变量伪共享;
    boolean flag;
    long c1,c2,c3,c4,c5,c6,c7,c8;//
    long createTime;
    char key;
    long d1,d2,d3,d4,d5,d6,d7,d8;//防止与下一个对象产生伪共享
}

@SuppressWarnings("restriction")
class ContendedGroupData {
    @sun.misc.Contended("group1")
    int value;
    @sun.misc.Contended("group1")
    long modifyTime;
    @sun.misc.Contended("group2")
    boolean flag;
    @sun.misc.Contended("group3")
    long createTime;
    @sun.misc.Contended("group3")
    char key;
}

/*
10000*10000L
readKeyThread:58
modifyFlagThread:61
modifyValueThread:86

readKeyThread:43
modifyFlagThread:68
modifyValueThread:77


 */